import axios, { AxiosRequestConfig } from 'axios';
import { Storage } from '@/utils/Storage';
import { ACCESS_TOKEN_KEY } from '@/core/cacheEnum';
// import { UseruStore } from '@/store';

export interface RequestOptions {
  /** 当前接口权限, 不需要鉴权的接口请忽略， 格式：sys:user:add */
  permCode?: string;
  /** 是否直接获取data，而忽略message等 */
  isGetDataDirectly?: boolean;
  /** 请求成功是提示信息 */
  successMsg?: string;
  /** 请求失败是提示信息 */
  errorMsg?: string;
  /** 是否mock数据请求 */
  isMock?: boolean;
}

const UNKNOWN_ERROR = '未知错误，请重试';

/** 真实请求的路径前缀 */
// const baseApiUrl = import.meta.env.VITE_BASE_API;
/** mock请求路径前缀 */
// const baseMockUrl = import.meta.env.VITE_MOCK_API;
const service = axios.create({
  // baseURL: baseApiUrl,
  timeout: 30000,
  // 6000
});
// const UNKNOWN_ERROR = '未知错误，请重试';

service.interceptors.request.use(
  (config) => {
    const token = Storage.get(ACCESS_TOKEN_KEY);
    if (token && config.headers) {
      // 请求头token信息，请根据实际情况进行修改
      // config.headers['Authorization'] = token;
    }
    if (config.responseType) {
      config.responseType = 'blob';
    }
    return config;
  },
  (error) => {
    Promise.reject(error);
  },
);

service.interceptors.response.use(
  (response) => {
    const res = response.data;
    if (res.length || res.length === 0) {
      return res;
    }

    // if the custom code is not 200, it is judged as an error.
    if (res.code !== 0) {
      ElMessage.error(res.msg || res.message || UNKNOWN_ERROR);

      // Illegal token
      if (res.code === 11001 || res.code === 11002) {
        window.localStorage.clear();
        window.location.reload();
      }

      // throw other
      const error = new Error(res.msg || res.message || UNKNOWN_ERROR) as Error & { code: any };
      error.code = res.code;
      return Promise.reject(error);
    } else {
      return res;
    }
  },
  (error) => {
    // 处理 422 或者 500 的错误异常提示
    const errMsg = error?.response?.data?.message ?? UNKNOWN_ERROR;
    ElMessage.error(errMsg);
    error.message = errMsg;
    return Promise.reject(error);
  },
);

// 解构
export type Response<T = any> = {
  code: number;
  msg: string;
  data: T;
};

export type BaseResponse<T = any> = Promise<Response<T>>;

/**
 *
 * @param method - request methods
 * @param url - request url
 * @param data - request data or params
 */
export const request = async <T = any>(
  config: AxiosRequestConfig,
  options: RequestOptions = {},
): Promise<T> => {
  try {
    const { successMsg, errorMsg, permCode, isMock, isGetDataDirectly = true } = options;
    console.log(permCode, isMock);
    // 如果当前是需要鉴权的接口 并且没有权限的话 则终止请求发起
    // if (permCode && !UseruStore().perms.includes(permCode)) {
    // return ElMessage.error('你没有访问该接口的权限，请联系管理员！');
    // }
    // const fullUrl = `${(isMock ? baseMockUrl : baseApiUrl) + config.url}`;
    // config.url = fullUrl.replace(/(?<!:)\/{2,}/g, '/');
    const res = await service.request(config);
    successMsg && ElMessage.success(successMsg);
    errorMsg && ElMessage.error(errorMsg);
    return isGetDataDirectly ? res.data : res;
  } catch (error: any) {
    return Promise.reject(error);
  }
};

/**
 * 文件下载
 * @param config 请求头
 * @param fileName 文件名字
 */
export const downloadFile = async (config: AxiosRequestConfig, fileName: string) => {
  try {
    const response = await axios(config);

    const urlObject = window.URL || window.webkitURL;
    const blob = new Blob([response.data]);
    const link = urlObject.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = link;
    a.download = fileName;
    a.click();

    urlObject.revokeObjectURL(link);
  } catch (error) {
    console.error('文件下载出错:', error);
  }
};
